using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Net;
using System.Web;
using iPhOwa.Exchange.ContentClasses;
using iPhOwa.Exchange.ContentClasses.Fields;
using iPhOwa.Exchange.WebDav.Methods;

namespace iPhOwa.Exchange.Managers
{
	/// <summary>
	/// Encapulates working with messages.
	/// </summary>
	public static class MessageManager
	{
		/// <summary>
		/// Get a single message.
		/// </summary>
		public static Message Get(Uri path, OwaSession session)
		{
			var properties = new[]
			                 	{
			                 			MessageFields.DateReceived
			                 			, MessageFields.FromName
			                 			, MessageFields.DisplayTo
			                 			, MessageFields.DisplayCC
			                 			, MessageFields.Priority
			                 			, MessageFields.Subject
			                 			, MessageFields.FlagCompleted
			                 			, MessageFields.MessageFlag
			                 			, ItemFields.ParentName
			                 			, ItemFields.Read
			                 			, MessageFields.To
			                 			, MessageFields.CC
			                 			, MessageFields.From
			                 			, MessageFields.NormalizedSubject
			                 			, MessageFields.TextDescription
			                 			, MessageFields.HasAttachment
			                 	};

			var propFind = new PropFind(path, session, properties);

			return (Message)propFind.Run();
		}

		/// <summary>
		/// Get's a list of message.
		/// </summary>
		/// <param name="path">The folder to get messages from.</param>
		/// <param name="startItem">The start index.</param>
		/// <param name="endItem">The end index.</param>
		/// <param name="session">The current session.</param>
		/// <returns>A collection of message items.</returns>
		public static ICollection<Message> GetList(Uri path, int startItem, int endItem, OwaSession session)
		{
			var properties = new[]
			                 	{
			                 			ItemFields.Read
			                 			, ItemFields.Href
			                 			, MessageFields.DateReceived
			                 			, MessageFields.FromName
			                 			, MessageFields.HasAttachment
			                 			, MessageFields.Priority
			                 			, MessageFields.Subject
			                 			, MessageFields.FlagCompleted
			                 			, MessageFields.MessageFlag
			                 	};

			var search = new Search(path, session, properties) {Range = new Range(startItem, endItem)};

			var items = new List<Item>(search.Run());

			return items.ConvertAll(i => i as Message);
		}

		/// <summary>
		/// Mark the specified message as read.
		/// </summary>
		public static void MarkAsRead(Uri path, OwaSession session)
		{
			IDictionary<string, object> properties = new Dictionary<string, object> {{ItemFields.Read, 1}};

			var propPatch = new PropPatch(path, session, properties);

			propPatch.Run();
		}

		/// <summary>
		/// Move an item to the specified destination.
		/// </summary>
		[SuppressMessage("Microsoft.Usage", "CA2234:PassSystemUriObjectsInsteadOfStrings")]
		public static void Move(Uri path, Uri destination, OwaSession session)
		{
			destination = new Uri(destination, Path.GetFileName(HttpUtility.HtmlEncode(path.LocalPath)));

			var move = new Move(path, destination, session);
			move.Run();
		}

		/// <summary>
		/// Save a message.
		/// </summary>
		/// <param name="path"></param>
		/// <param name="content"></param>
		/// <param name="session"></param>
		public static void Save(Uri path, string content, OwaSession session)
		{
			IDictionary<string, string> headers = new Dictionary<string, string> {{"Translate", "f"}};

			var put = new Put(path, session, content, headers, "message/rfc822");
			put.Run();
		}

		/// <summary>
		/// Send a message.
		/// </summary>
		/// <param name="tempUri"></param>
		/// <param name="mailSubmissionUri"></param>
		/// <param name="content"></param>
		/// <param name="session"></param>
		public static void Send(Uri tempUri, Uri mailSubmissionUri, string content, OwaSession session)
		{
			Save(tempUri, content, session);
			Move(tempUri, mailSubmissionUri, session);
		}

		/// <summary>
		/// Get all the attachments for a message.
		/// </summary>
		/// <param name="path"></param>
		/// <param name="session"></param>
		public static ICollection<Attachment> GetAttachments(Uri path, OwaSession session)
		{
			var method = new XMSEnumAtts(path, session);
			return method.Run();
		}

		/// <summary>
		/// Get an attachment.
		/// </summary>
		/// <param name="path"></param>
		/// <param name="session"></param>
		/// <returns></returns>
		public static WebResponse GetAttachment(Uri path, OwaSession session)
		{
			var method = new Get(path, session);
			return method.Run();
		}
	}
}